package com.alibobo.tech5.ganji;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.alibobo.utils.file.FileUtils;
import com.alibobo.utils.json.JsonUtils;

public class GJR {

	protected static GJR _instance = new GJR();
	protected static JSONObject _rootJ = null;

	public static boolean loadRes() {
		String file = "com/alibobo/tech5/ganji/GanToJi.json";
		InputStream in = _instance.getClass().getClassLoader()
				.getResourceAsStream(file);
		String content = FileUtils.readInputStreamAsString(in);
		JSONObject jo = null;
		try {
			jo = new JSONObject(content);
		} catch (JSONException e) {
			e.printStackTrace();
			return false;
		}
		_rootJ = jo;
		return true;
	}

	protected static String[] _地支 = { "亥", "子", "丑", "寅", "卯", "辰", "巳", "午",
			"未", "申", "酉", "戌", "亥" };
	protected static String[] _天干 = { "癸", "甲", "乙", "丙", "丁", "戊", "己", "庚",
			"辛", "壬", "癸" };

	public static String offset(String gj, int offset) {
		if (_gan2Id.containsKey(gj)) {
			int id = _gan2Id.get(gj) + offset;
			return id2Gan(id);
		}
		if (_ji2Id.containsKey(gj)) {
			int id = _ji2Id.get(gj) + offset;
			return id2Ji(id);
		}
		return "";
	}

	static final Map<String, Integer> _gan2Id = new HashMap<String, Integer>() {
		{
			put("甲", 1);
			put("乙", 2);
			put("丙", 3);
			put("丁", 4);
			put("戊", 5);
			put("己", 6);
			put("庚", 7);
			put("辛", 8);
			put("壬", 9);
			put("癸", 10);
		}
	};
	static final Map<Integer, String> _id2Gan = new HashMap<Integer, String>() {
		{
			put(1, "甲");
			put(2, "乙");
			put(3, "丙");
			put(4, "丁");
			put(5, "戊");
			put(6, "己");
			put(7, "庚");
			put(8, "辛");
			put(9, "壬");
			put(10, "癸");
			put(0, "癸");
		}
	};

	static final Map<String, Integer> _ji2Id = new HashMap<String, Integer>() {
		{
			put("子", 1);
			put("丑", 2);
			put("寅", 3);
			put("卯", 4);
			put("辰", 5);
			put("巳", 6);
			put("午", 7);
			put("未", 8);
			put("申", 9);
			put("酉", 10);
			put("戌", 11);
			put("亥", 12);
		}
	};
	static final Map<Integer, String> _id2Ji = new HashMap<Integer, String>() {
		{
			put(1, "子");
			put(2, "丑");
			put(3, "寅");
			put(4, "卯");
			put(5, "辰");
			put(6, "巳");
			put(7, "午");
			put(8, "未");
			put(9, "申");
			put(10, "酉");
			put(11, "戌");
			put(12, "亥");
			put(0, "亥");
		}
	};

	public static String pickFirstWord(String gj) {
		if (gj == null)
			return null;

		int sz = gj.length();
		return sz > 1 ? gj.substring(0, 1) : gj;
	}

	public static String pickLastWord(String gj) {
		if (gj == null)
			return null;
		int sz = gj.length();
		return sz > 1 ? gj.substring(sz - 1) : gj;
	}

	public static String id2Gan(int id) {
		while (id < 0)
			id += 10;
		while (id > 10)
			id -= 10;
		return _天干[id];
	}

	public static String id2Ji(int id) {
		while (id < 0)
			id += 12;
		while (id > 12)
			id -= 12;
		return _地支[id];
	}

	public static Integer ganId(String gan) {
		gan = pickFirstWord(gan);
		return _gan2Id.get(gan);
	}

	public static int jiId(String ji) {
		ji = pickLastWord(ji);
		return GJR._ji2Id.get(ji);
	}

	public static String nextGan(String gan) {
		int id = GJR._gan2Id.get(gan);
		return id2Gan(id++);
	}

	public static String prevGan(String gan) {
		int id = GJR._gan2Id.get(gan);
		return id2Gan(id--);
	}

	public static String nextJi(String ji) {
		int id = GJR._ji2Id.get(ji);
		return GJR.id2Ji(id++);
	}

	public static String prevJi(String ji) {
		int id = GJR._ji2Id.get(ji);
		return GJR.id2Ji(id--);
	}

	public static String 六十甲子fromId(int id) {
		int g = id % 10;
		int j = id % 12;
		return _id2Gan.get(g) + _id2Ji.get(j);
	}

	public static String 六十甲子fromId(int id, int off1, int off2) {
		int g = (id + off1) % 10;
		int j = (id + off2) % 12;
		return _id2Gan.get(g) + _id2Ji.get(j);
	}

	public static int 六十甲子(String gj) {
		int g1, j1;
		g1 = ganId(pickFirstWord(gj));
		if (g1 == 0)
			g1 = 10;
		j1 = jiId(pickLastWord(gj));
		int off = (12 + j1 - g1) % 12;
		// 超前代表後退幾次 ~~
		int start1 = 1 + off;
		int step = (12 - off) / 2;
		int of = (j1 - start1 + 12) % 12;
		int pos = step * 10 + of + 1;
		return pos;

	}

	protected static String fetchValueByKey(JSONObject src, String key) {
		try {
			Iterator it = src.keys();
			while (it.hasNext()) {
				String k = (String) it.next();
				if (k.equals(key)) {
					String v = (String) src.get(k);
					return v;
				}
			}
			return "";
		} catch (Exception e) {
			return "";
		}
	}

	public static String get支神(String ji) {
		try {
			JSONObject _支神 = _rootJ.getJSONObject("支神");
			return fetchValueByKey(_支神, ji);
		} catch (Exception e) {
			return "";
		}
	}

	public static String get天干寄宮(String gan) {
		try {
			JSONObject _天干寄宮 = _rootJ.getJSONObject("天干寄宮");
			return fetchValueByKey(_天干寄宮, gan);
		} catch (Exception e) {
			return "";
		}

	}

	public static Hashtable<String, String> get遁干表(String ganji) {
		String first = get旬首(ganji);
		int fid = jiId(first);
		Hashtable<String, String> result = new Hashtable<String, String>();
		for (int i = 0; i < 12; i++) {

			if (i < 10)
				result.put(id2Ji(fid + i), id2Gan(i + 1));
			else
				result.put(id2Ji(fid + i), "");
		}
		return result;
	}

	public static String get旬首(String ganji) {
		int gId = ganId(pickFirstWord(ganji));
		int jId = jiId(pickLastWord(ganji));
		int off = jId - gId;
		if (off < 0)
			off += 12;
		return id2Ji(off + 1);
	}

	public static String 旬奇(String ganji) {
		String head = GJR.get旬首(ganji);
		if ("子戌".indexOf(head) != -1)
			return "丑";
		if ("申午".indexOf(head) != -1)
			return "子";
		if ("辰寅".indexOf(head) != -1)
			return "亥";
		return "";
	}

	public static String 旬遁(String ganji, String gan) {
		String start = get旬首(ganji);
		int gi = ganId(gan);
		int ji = jiId(start);
		return id2Ji(ji + gi - 1);
	}

	public static String 干支五行(String item) {
		try {
			JSONObject _干支五行 = _rootJ.getJSONObject("干支五行");
			return fetchValueByKey(_干支五行, item);
		} catch (Exception e) {
			return "";
		}
	}

	public static List<String> 天將() {
		try {
			JSONArray jo = _rootJ.getJSONArray("天將");
			return JsonUtils.readStringArrayFrom(jo);
		} catch (Exception e) {
			return new ArrayList<String>();
		}

	}

	public static List<String> 天將逆行() {
		try {
			JSONArray jo = _rootJ.getJSONArray("天將逆行");
			return JsonUtils.readStringArrayFrom(jo);
		} catch (Exception e) {
			return new ArrayList<String>();
		}
	}

	protected static JSONArray fetchJSONArrayByKey(JSONObject parent, String key) {
		Iterator it = parent.keys();
		try {
			while (it.hasNext()) {
				String k = (String) it.next();
				if (k.equals(key)) {
					return parent.getJSONArray(k);
				}
			}
			return null;
		} catch (Exception e) {
			return null;
		}
	}

	protected static JSONObject fetchJObjectByKey(JSONObject parent, String key) {
		Iterator it = parent.keys();
		try {
			while (it.hasNext()) {
				String k = (String) it.next();
				if (k.equals(key)) {
					return parent.getJSONObject(k);
				}
			}
			return null;
		} catch (Exception e) {
			return null;
		}
	}

	public static String 六親AofB(String A, String B) {
		String f5_1 = 干支五行(A);
		String f5_2 = 干支五行(B);
		try {
			JSONObject _五行六親 = _rootJ.getJSONObject("五行六親");
			JSONObject subt = fetchJObjectByKey(_五行六親, f5_2);
			return fetchValueByKey(subt, f5_1);
		} catch (Exception e) {
			return "";

		}
	}

	public static String fixGanJi(String gj) {
		String g = pickFirstWord(gj);
		String j = pickLastWord(gj);
		g = fixGan(g);
		j = fixJi(j);
		return g + j;
	}

	public static String fixGan(String g) {
		if ("已巳已".indexOf(g) != -1)
			return "己";
		return g;
	}

	public static String fixJi(String j) {
		if ("已己已".indexOf(j) != -1)
			return "巳";
		if ("戍".indexOf(j) != -1)
			return "戌";
		return j;
	}

	public static String 五鼠遁(String 日干, String 時干支) {
		時干支 = GJR.pickLastWord(時干支);
		int off = GJR.jiId(時干支) - GJR.jiId("子");
		if (off < 0)
			off += 12;
		日干 = GJR.pickFirstWord(日干);
		String startGan = "";
		if ("甲己".indexOf(日干) != -1)
			startGan = "甲";
		if ("乙庚".indexOf(日干) != -1)
			startGan = "丙";
		if ("丙辛".indexOf(日干) != -1)
			startGan = "戊";
		if ("丁壬".indexOf(日干) != -1)
			startGan = "庚";
		if ("戊癸".indexOf(日干) != -1)
			startGan = "壬";

		int id = (GJR.ganId(startGan) + off) % 10;
		return GJR.id2Gan(id) + 時干支;
	}

	public static Boolean isDay(String ji) {
		ji = pickLastWord(ji);
		int id = jiId(ji);
		if ((jiId("卯") <= id) && (id <= jiId("申"))) {
			return true;
		}
		return false;
	}

	protected static String[] 女命行年干 = { "癸", "壬", "辛", "庚", "己", "戊", "丁", "丙",
			"乙", "甲" };
	protected static String[] 女命行年支 = { "酉", "申", "未", "午", "巳", "辰", "卯", "寅",
			"丑", "子", "亥", "戌" };

	public static String 女命行年(int year) {
		int g = year % 10;
		int j = year % 12;
		return 女命行年干[g] + 女命行年支[j];
	}

	public static String 行年(String 本命, String 太歲, Boolean male) {
		int b = 六十甲子(本命);
		int now = 六十甲子(太歲);
		int off = (now + 60 - b) % 60;
		if (male)
			return 六十甲子fromId(off + 3);
		return 女命行年(off + 1);
	}

}
